package com.idol.logger.core.printer.file

import com.idol.logger.utils.times
import java.io.BufferedWriter
import java.io.File
import java.io.FileWriter
import java.io.IOException

internal class IdolFileWriter(private val path: String) {
    companion object {
        private val SEPARATOR = "-" * 100
    }

    private var fileName: String = ""
    private var bufferWriter: BufferedWriter? = null

    /**
     * init io objects.
     * @param name save file name.
     */
    fun ready(name: String): Boolean {
        if (fileName == name && bufferWriter != null) return true
        close() // release io object.
        return File(path, name.also { fileName = name }).let { file ->
            if (!file.exists()) {
                try {
                    file.parentFile?.also { parent ->
                        if (!parent.exists()) parent.mkdirs()
                        parent.createNewFile()
                    }
                } catch (e: IOException) {
                    return@let failed(e, true)
                }
            }
            try {
                bufferWriter = BufferedWriter(FileWriter(file, true))
            } catch (e: IOException) {
                return@let failed(e, true)
            }
            return@let true
        }
    }

    /**
     * print message to file.
     */
    fun append(message: String): Boolean = bufferWriter?.run {
        try {
            write(message); newLine(); write(SEPARATOR); newLine(); flush(); true
        } catch (e: IOException) {
            failed(e, true)
        }
    } ?: false

    private fun failed(e: IOException?, close: Boolean) = false.also {
        e?.printStackTrace()
        if (close) close()
    }

    /**
     * release io object.
     */
    private fun close() {
        try {
            bufferWriter?.close()
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            fileName = ""
            bufferWriter = null
        }
    }

}